#pragma once
#include<iostream>
#include<vector>
#include<queue>
#include"Thread.hpp"

using namespace std;
const int g_thread_num=3;

template <class T>
class ThreadPool
{
public:
    pthread_mutex_t* getMutex()
    {
        return &lock;
    }
    bool isEmpty()
    {
        return task_queue.empty();
    }
    void waitCond()
    {
        pthread_cond_wait(&cond,&lock);
    }
    T getTask()
    {
        //获取一个任务
        T t=task_queue.front();
        task_queue.pop();
        return t;
    }
public:
    //获取线程池的指针
    static Threadpool<T>* getThreadPool(int num=g_thread_num)
    {
        if(thread_ptr==nullptr)
        {
            LockGuard lockguard(&mutex);

        }
    }
    static ThreadPool<T>* getThreadPool(int num=g_thread_num)
    {
        if(thread_ptr==nullptr)
        {
            lockGuard lockguard(&mutex);
            if(thread_ptr==nullptr)
            {
                thread_ptr=new ThreadPool<T>(num);
            }
        }
        return thread_ptr;
    }
    void run()
    {
        for(auto& iter:_threads)
        {
            iter->start();
        }
    }
    static void* routine(void* args)
    {
        ThreadData* td=(ThreadData)* args;
        ThreadPool<T>* tp=(ThreadPool<T>*)td->_args;
        while(true)
        {
            T task;
            {
                LockGuard lockguard(tp->getMutex());
                while(tp->isEmpty())
                {
                    tp->waitCond();
                    task=tp->getTask();
                }
                task(td->_name);
            }
        }
    }
    void push_back(const T& task)
    {
        lockGuard lockguard(&lock);
        task_queue.push(task);
        pthread_cond_signal(&cond);
    }
    ~ThreadPool()
    {
        for(auto &iter:_threads)
        {
            iter->join();
            delete iter;
        }
        //将锁和环境变量全部销毁
        pthread_mutex_destroy(&lock);
        pthread_cond_destroy(&cond);
    }
private:
    vector<Thread*> _threads;
    int _num;
    queue<T> task_queue;
    static ThreadPool<T>* thread_ptr;
    static pthread_mutex_t mutex;
    pthread_mutex_t lock;
    pthread_cond_t cond;
};
